package com.androidhuman.example.mapsv2example;

import java.io.IOException;
import java.util.List;
import java.util.Locale;

import android.app.AlertDialog;
import android.app.Service;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings;
import android.util.Log;
import android.widget.Toast;

public class GPSTracker extends Service implements LocationListener {

	private final Context mContext;
	public String address=null;

	// GPS가 켜져 있는가?
	boolean isGPSEnabled = false;

	// NETWORK가 켜져 있는가?
	boolean isNetworkEnabled = false;

	// GPS로 부터 위치 파악가능한가?
	boolean canGetLocation = false;

	Location location; // 위치
	static double latitude;   // 위도
	static double longitude;  // 경도

	// 업데이트할 최소 거리
	private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters

	// 업데이트 최소 시간
	private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute

	// LocationManager 선언
	protected LocationManager locationManager;

	public GPSTracker(Context context) {
		this.mContext = context;
		getLocation();
	}

	public Location getLocation() {
		try {
			locationManager = (LocationManager) mContext
					.getSystemService(LOCATION_SERVICE);

			// GPS 상태 받아옴
			isGPSEnabled = locationManager
					.isProviderEnabled(LocationManager.GPS_PROVIDER);

			// NETWORK 상태 받아옴
			isNetworkEnabled = locationManager
					.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

			if (!isGPSEnabled && !isNetworkEnabled) {
				// 네트워크 제공자 없음
			} else {
				this.canGetLocation = true;
				// 네트워크를 사용해 위치정보 받음
				if (isNetworkEnabled) {
					locationManager.requestLocationUpdates(
							LocationManager.NETWORK_PROVIDER,
							MIN_TIME_BW_UPDATES,
							MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
					Log.d("Network", "Network");
					if (locationManager != null) {
						location = locationManager
								.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
						if (location != null) {
							latitude = location.getLatitude();
							longitude = location.getLongitude();
							address=getAddress(latitude,longitude);
						}
					}
				}
				// GPS 사용 가능하면 GPS로 부터 받는다
				if (isGPSEnabled) {
					if (location == null) {
						locationManager.requestLocationUpdates(
								LocationManager.GPS_PROVIDER,
								MIN_TIME_BW_UPDATES,
								MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
						Log.d("GPS Enabled", "GPS Enabled");
						if (locationManager != null) {
							location = locationManager
									.getLastKnownLocation(LocationManager.GPS_PROVIDER);
							if (location != null) {
								latitude = location.getLatitude();
								longitude = location.getLongitude();
								address=getAddress(latitude,longitude);
							}
						}
					}
				}
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
		address=getAddress(latitude,longitude);
		return location;
	}

	/**
	 * GPS 멈춤이
	 * */
	public void stopUsingGPS(){
		if(locationManager != null){
			locationManager.removeUpdates(GPSTracker.this);
		}       
	}

	/**
	 * 위도 알림이
	 * */
	public double getLatitude(){
		if(location != null){
			latitude = location.getLatitude();
		}

		// 위도 값 반환
		return latitude;
	}

	/**
	 * 경도 알림이
	 * */
	public double getLongitude(){
		if(location != null){
			longitude = location.getLongitude();
		}

		// 경도값 반환
		return longitude;
	}

	/**
	 * GPS/WIFI로 부터 위치를 구할 수 있는가
	 * @return boolean
	 * */
	public boolean canGetLocation() {
		return this.canGetLocation;
	}

	public String getAddress(double lat, double lng){
		String address = null;

		//위치정보를 활용하기 위한 구글 API 객체
		Geocoder geocoder = new Geocoder(mContext, Locale.getDefault());

		//주소 목록을 담기 위한 HashMap
		List<Address> list = null;

		try{
			list = geocoder.getFromLocation(lat, lng, 1);
		} catch(Exception e){
			e.printStackTrace();
		}

		if(list == null){
			Log.e("getAddress", "주소 데이터 얻기 실패");
			return null;
		}

		if(list.size() > 0){
			Address addr = list.get(0);
			address="";
			if(addr.getCountryName()!=null){address += addr.getCountryName() + " ";}
			if(addr.getAdminArea()!=null){address += addr.getAdminArea() + " ";}
			if(addr.getPostalCode()!=null){address += addr.getPostalCode() + " ";}
			if(addr.getLocality()!=null){address += addr.getLocality() + " ";}
			if(addr.getThoroughfare()!=null){address += addr.getThoroughfare() + " ";}
			if(addr.getFeatureName()!=null){address += addr.getFeatureName() + " ";}

		}
		return address;}



		//이건 뭔지 모르겠다.
		/**
		 * Function to show settings alert dialog
		 * On pressing Settings button will lauch Settings Options
		 * */
		public void showSettingsAlert(){
			AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);

			// Setting Dialog Title
			alertDialog.setTitle("GPS is settings");

			// Setting Dialog Message
			alertDialog.setMessage("GPS is not enabled. Do you want to go to settings menu?");

			// On pressing Settings button
			alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
				public void onClick(DialogInterface dialog,int which) {
					Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
					mContext.startActivity(intent);
				}
			});

			// on pressing cancel button
			alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
				public void onClick(DialogInterface dialog, int which) {
					dialog.cancel();
				}
			});

			// Showing Alert Message
			alertDialog.show();
		}

		@Override
		public void onLocationChanged(Location location) {
		}

		@Override
		public void onProviderDisabled(String provider) {
		}

		@Override
		public void onProviderEnabled(String provider) {
		}

		@Override
		public void onStatusChanged(String provider, int status, Bundle extras) {
		}

		@Override
		public IBinder onBind(Intent arg0) {
			return null;
		}

	}